package modelo;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import modelo.adaptadores.ClienteAdapter;
import modelo.enums.Tarifa;

@XmlSeeAlso({ Persona.class, Empresa.class })
@XmlTransient
@XmlJavaTypeAdapter(ClienteAdapter.class)
@Entity
@Table(name = "cliente")
@Inheritance(strategy = InheritanceType.JOINED)
@NamedQueries({
        @NamedQuery(name = Cliente.RECUPERA_TODOS, query = "SELECT c FROM Cliente c"),
        @NamedQuery(name = Cliente.RECUPERA_POR_NIF, query = "SELECT e FROM Cliente e WHERE e.nif = :nif") })
abstract public class Cliente
{
    public static final String RECUPERA_TODOS = "Recupera todos los clientes";
    public static final String RECUPERA_POR_NIF = "Recupera los clientes de un NIF";
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String nombre;
    private String nif;
    @OneToOne(cascade = CascadeType.PERSIST)
    private Direccion direccion;
    @Enumerated
    private Tarifa tarifa;

    public Cliente()
    {
        super();
    }

    public Cliente(String nombre, String nif, Direccion direccion, Tarifa tarifa)
    {
        super();
        this.nombre = nombre;
        this.nif = nif;
        this.direccion = direccion;
        this.tarifa = tarifa;
    }

    public String getNombre()
    {
        return nombre;
    }

    public void setNombre(String nombre)
    {
        this.nombre = nombre;
    }

    public String getNif()
    {
        return nif;
    }

    public void setNif(String nif)
    {
        this.nif = nif;
    }

    public Direccion getDireccion()
    {
        return direccion;
    }

    public void setDireccion(Direccion direccion)
    {
        this.direccion = direccion;
    }

    public Tarifa getTarifa()
    {
        return tarifa;
    }

    public void setTarifa(Tarifa tarifa)
    {
        this.tarifa = tarifa;
    }

    public void actualiza(Cliente cliente)
    {
    }

    public abstract ClienteAdapter.AdaptedCliente mapea();

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((direccion == null) ? 0 : direccion.hashCode());
        result = prime * result + ((nif == null) ? 0 : nif.hashCode());
        result = prime * result + ((nombre == null) ? 0 : nombre.hashCode());
        result = prime * result + ((tarifa == null) ? 0 : tarifa.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Cliente other = (Cliente) obj;
        if (direccion == null)
        {
            if (other.direccion != null)
                return false;
        }
        else if (!direccion.equals(other.direccion))
            return false;
        if (nif == null)
        {
            if (other.nif != null)
                return false;
        }
        else if (!nif.equals(other.nif))
            return false;
        if (nombre == null)
        {
            if (other.nombre != null)
                return false;
        }
        else if (!nombre.equals(other.nombre))
            return false;
        if (tarifa != other.tarifa)
            return false;
        return true;
    }

}